package com.king.controller;


import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.king.common.lang.Result;
import com.king.config.RabbitmqConfig;
import com.king.entity.MComment;
import com.king.entity.MPost;
import com.king.entity.MUser;
import com.king.entity.MUserMessage;
import com.king.search.mq.PostMQIndexMessage;
import com.king.util.ValidationUtil;
import com.king.vo.MCommentVo;
import com.king.vo.MPostVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import java.util.Date;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author KING
 * @since 2020-09-01
 */
@Controller
@RequestMapping("/post")
public class MPostController extends BaseController {
    /**
     * 获取博客详情
     * @param id
     * @return
     */
    @GetMapping("/{id:\\d*}")//【:\d*】过滤掉类似post/add等
    public String detail(@PathVariable(name = "id") Long id){
        MPostVo vo = mPostService.selectOnePost(new QueryWrapper<MPost>().eq("p.id",id));
        Assert.notNull(vo,"此文章已被删除！");

        mPostService.putViewCount(vo);

        request.setAttribute("post",vo);
        request.setAttribute("currentCategoryId",vo.getCategoryId());

        //1分页, 2文章id, 3用户id, 4排序
        IPage<MCommentVo> results = mCommentService.paging(getPage(),vo.getId(),null,"created");
        request.setAttribute("pageData",results);

        return "post/detail";
    }

    @GetMapping("/edit")
    public String edit(){
        String pid = request.getParameter("id");
        if(StringUtils.isNotBlank(pid)){
            MPost post = mPostService.getById(pid);
            Assert.notNull(post,"该博客已被删除！");
            Assert.isTrue(post.getUserId() == getProfileId(),"无权限编辑该文章！");
            request.setAttribute("post",post);
        }

        request.setAttribute("categories",mCategoryService.list());

        return "post/edit";
    }

    @ResponseBody
    @PostMapping("/submit")
    public Result submit(MPost post){
        ValidationUtil.ValidResult validResult = ValidationUtil.validateBean(post);
        if(validResult.hasErrors()){
            return Result.fail(validResult.getErrors());
        }

        MPost tmp;
        boolean isTrue;
        if(post.getId() == null){//添加
            tmp = new MPost();
            tmp.setTitle(post.getTitle());
            tmp.setCategoryId(post.getCategoryId());
            tmp.setContent(post.getContent());
            tmp.setViewCount(0);
            tmp.setCommentCount(0);
            tmp.setLevel(0);
            tmp.setRecommend(false);
            tmp.setUserId(getProfileId());
            tmp.setEditMode(null);
            tmp.setVoteUp(0);
            tmp.setVoteDown(0);
            tmp.setCreated(new Date());
            tmp.setModified(new Date());
            isTrue = mPostService.save(tmp);
        }else{//编辑
            tmp = mPostService.getById(post.getId());
            Assert.notNull(tmp,"该博客已被删除！");
            Assert.isTrue(tmp.getUserId() == getProfileId(),"无权限编辑此博客！");
            tmp.setTitle(post.getTitle());
            tmp.setContent(post.getContent());
            tmp.setCategoryId(post.getCategoryId());
            tmp.setModified(new Date());
            isTrue = mPostService.updateById(tmp);
        }

        //通知消息到mq,告知更新或增加
        amqpTemplate.convertAndSend(RabbitmqConfig.es_exchange,RabbitmqConfig.es_bind_key,new PostMQIndexMessage(tmp.getId(),PostMQIndexMessage.CREATE_OR_UPDATE));

        return isTrue?Result.success().action("/post/"+tmp.getId()):Result.fail("操作失败！");
    }

    @Transactional
    @ResponseBody
    @PostMapping("/delete")
    public Result delete(Long id){
        MPost post = mPostService.getById(id);
        Assert.notNull(post,"该博客已被删除！");
        Assert.isTrue(post.getUserId() == getProfileId(),"无权限编辑该博客！");

        mPostService.removeById(id);

        //删除相关消息、收藏等
        mUserMessageService.removeByMap(MapUtil.of("post_id",id));
        mUserCollectionService.removeByMap(MapUtil.of("post_id",id));

        //通知消息到mq,告知删除
        amqpTemplate.convertAndSend(RabbitmqConfig.es_exchange,RabbitmqConfig.es_bind_key,new PostMQIndexMessage(post.getId(),PostMQIndexMessage.REMOVE));

        return Result.success().action("/user/index");
    }

    @ResponseBody
    @PostMapping("/reply")
    public Result reply(Long pid,String content){
        Assert.notNull(pid,"博客id不能为空！");
        Assert.hasLength(content,"评论内容不能为空！");

        MPost post = mPostService.getById(pid);
        Assert.notNull(post,"该博客已被删除！");

        MComment comment = new MComment();
        comment.setPostId(pid);
        comment.setContent(content);
        comment.setUserId(getProfileId());
        comment.setCreated(new Date());
        comment.setModified(new Date());
        comment.setLevel(0);
        comment.setVoteDown(0);
        comment.setVoteUp(0);
        /*if(content.startsWith("@")){
            comment.setParentId(null);//需由前端传递过来？ 设置了该值就不会在消息里无法显示被评论的内容
        }*/
        mCommentService.save(comment);//保存评论文章的记录

        post.setCommentCount(post.getCommentCount()+1);
        mPostService.updateById(post);//更新文章的评论数量

        mPostService.updateCommentCountAndUnionForWeekRank(post.getId(),true);//更新本周热议

        notifyAuthor(post,comment);
        notifyCommenter(post,comment);

        return  Result.success().action("/post/"+post.getId());
    }

    /**
     * 通知文章作者，有人评论了你的文章
     * @param post
     * @param comment
     */
    private void notifyAuthor(MPost post, MComment comment) {
        if(comment.getUserId() != post.getUserId()){//作者评论自己文章，不通知
            MUserMessage message = new MUserMessage();
            message.setPostId(post.getId());
            message.setCommentId(comment.getId());
            message.setContent(comment.getContent());
            message.setFromUserId(getProfileId());
            message.setToUserId(post.getUserId());
            message.setType(1);//评论文章
            message.setStatus(0);
            message.setCreated(new Date());
            message.setModified(new Date());
            mUserMessageService.save(message);//通知文章作者，有人评论了你的文章

            //即时通知作者（双工通讯：webSocket）
            webSocketService.sendMsgCount(message.getToUserId());
        }
    }

    /**
     * 通知被@的人，有人回复了你的评论
     * @param post
     * @param comment
     */
    private void notifyCommenter(MPost post, MComment comment) {
        if(comment.getContent().startsWith("@")){
            String userName = comment.getContent().substring(1,comment.getContent().indexOf(" "));
            MUser user = mUserService.getOne(new QueryWrapper<MUser>().eq("username", userName));
            if(user !=null){
                MUserMessage message = new MUserMessage();
                message.setPostId(post.getId());
                message.setCommentId(comment.getId());
                message.setContent(comment.getContent());
                message.setFromUserId(getProfileId());
                message.setToUserId(user.getId());
                message.setType(2);//评论评论
                message.setStatus(0);
                message.setCreated(new Date());
                message.setModified(new Date());
                mUserMessageService.save(message);//通知被@的人，有人回复了你的评论

                //即时通知被@的人（双工通讯：webSocket）
                webSocketService.sendMsgCount(message.getToUserId());
            }
        }
    }
}
